const CryptoJS = require('../aliyun/CryptoJS/crypto-js.js');
const formatTime = date => {
  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const hour = date.getHours()
  const minute = date.getMinutes()
  const second = date.getSeconds()
  var week = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
  var weekDate = year + '/' + month + '/' + day
  var weekNum = new Date(weekDate).getDay()
  const datetime = [[year, month, day].map(formatNumber).join('-'), [hour, minute, second].map(formatNumber).join(':'), week[weekNum]]
  return datetime
  // return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}

const formatTime1 = date => {
  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const hour = date.getHours()
  const minutes = date.getMinutes()

  const datetime = [year, month, day, hour, minutes]
  return datetime
}

const formatNumber = n => {
  n = n.toString()
  return n[1] ? n : '0' + n
}

const crctab16 =
[
  0X0000, 0X1189, 0X2312, 0X329B, 0X4624, 0X57AD, 0X6536, 0X74BF, 0X8C48, 0X9DC1, 0XAF5A, 0XBED3, 0XCA6C,
  0XDBE5, 0XE97E, 0XF8F7, 0X1081, 0X0108, 0X3393, 0X221A, 0X56A5, 0X472C, 0X75B7, 0X643E, 0X9CC9, 0X8D40,
  0XBFDB, 0XAE52, 0XDAED, 0XCB64, 0XF9FF, 0XE876, 0X2102, 0X308B, 0X0210, 0X1399, 0X6726, 0X76AF, 0X4434,
  0X55BD, 0XAD4A, 0XBCC3, 0X8E58, 0X9FD1, 0XEB6E, 0XFAE7, 0XC87C, 0XD9F5, 0X3183, 0X200A, 0X1291, 0X0318,
  0X77A7, 0X662E, 0X54B5, 0X453C, 0XBDCB, 0XAC42, 0X9ED9, 0X8F50, 0XFBEF, 0XEA66, 0XD8FD, 0XC974, 0X4204,
  0X538D, 0X6116, 0X709F, 0X0420, 0X15A9, 0X2732, 0X36BB, 0XCE4C, 0XDFC5, 0XED5E, 0XFCD7, 0X8868, 0X99E1,
  0XAB7A, 0XBAF3, 0X5285, 0X430C, 0X7197, 0X601E, 0X14A1, 0X0528, 0X37B3, 0X263A, 0XDECD, 0XCF44, 0XFDDF,
  0XEC56, 0X98E9, 0X8960, 0XBBFB, 0XAA72, 0X6306, 0X728F, 0X4014, 0X519D, 0X2522, 0X34AB, 0X0630, 0X17B9,
  0XEF4E, 0XFEC7, 0XCC5C, 0XDDD5, 0XA96A, 0XB8E3, 0X8A78, 0X9BF1, 0X7387, 0X620E, 0X5095, 0X411C, 0X35A3,
  0X242A, 0X16B1, 0X0738, 0XFFCF, 0XEE46, 0XDCDD, 0XCD54, 0XB9EB, 0XA862, 0X9AF9, 0X8B70, 0X8408, 0X9581,
  0XA71A, 0XB693, 0XC22C, 0XD3A5, 0XE13E, 0XF0B7, 0X0840, 0X19C9, 0X2B52, 0X3ADB, 0X4E64, 0X5FED, 0X6D76,
  0X7CFF, 0X9489, 0X8500, 0XB79B, 0XA612, 0XD2AD, 0XC324, 0XF1BF, 0XE036, 0X18C1, 0X0948, 0X3BD3, 0X2A5A,
  0X5EE5, 0X4F6C, 0X7DF7, 0X6C7E, 0XA50A, 0XB483, 0X8618, 0X9791, 0XE32E, 0XF2A7, 0XC03C, 0XD1B5, 0X2942,
  0X38CB, 0X0A50, 0X1BD9, 0X6F66, 0X7EEF, 0X4C74, 0X5DFD, 0XB58B, 0XA402, 0X9699, 0X8710, 0XF3AF, 0XE226,
  0XD0BD, 0XC134, 0X39C3, 0X284A, 0X1AD1, 0X0B58, 0X7FE7, 0X6E6E, 0X5CF5, 0X4D7C, 0XC60C, 0XD785, 0XE51E,
  0XF497, 0X8028, 0X91A1, 0XA33A, 0XB2B3, 0X4A44, 0X5BCD, 0X6956, 0X78DF, 0X0C60, 0X1DE9, 0X2F72, 0X3EFB,
  0XD68D, 0XC704, 0XF59F, 0XE416, 0X90A9, 0X8120, 0XB3BB, 0XA232, 0X5AC5, 0X4B4C, 0X79D7, 0X685E, 0X1CE1,
  0X0D68, 0X3FF3, 0X2E7A, 0XE70E, 0XF687, 0XC41C, 0XD595, 0XA12A, 0XB0A3, 0X8238, 0X93B1, 0X6B46, 0X7ACF,
  0X4854, 0X59DD, 0X2D62, 0X3CEB, 0X0E70, 0X1FF9, 0XF78F, 0XE606, 0XD49D, 0XC514, 0XB1AB, 0XA022, 0X92B9,
  0X8330, 0X7BC7, 0X6A4E, 0X58D5, 0X495C, 0X3DE3, 0X2C6A, 0X1EF1, 0X0F78,
];
// 计算给定长度数据的16 位CRC。
function GetCrc16(pData, nLength)
{
  var fcs = 0xffff // 初始化
  var i = 0
  while (nLength > 0) {
    fcs = (fcs >> 8) ^ crctab16[(fcs ^ pData[i]) & 0xff]
    nLength--
    i++
  }
  return ~fcs; // 取反
}
/**
 * @description: 二进制流数据结构
 * @param {type} 
 * @return: 
 */
function ByteArray() {
  this.list = [];
  this.byteOffset = 0;
  this.length = 0;
}
var p = ByteArray.prototype;
p.push = function (unit8Arr) {
  this.list.push(unit8Arr);
  this.length += unit8Arr.length;
}
/**
 * @description: 
 * @param {type} rbuf_ind:已经取到的buf长度 last_len:剩余未取到的buf长度
 * @return: 
 */
p.readBytes = function (len) {
  if (len > 0) {
    let rbuf = new Uint8Array(len);
    let rbuf_ind = 0;
    while (rbuf_ind < len) {
      if (this.list.length > 0) {
        let tmpbuf = this.list.shift();
        let tmplen = tmpbuf.length;
        let last_len = len - rbuf_ind;
        if (tmplen >= last_len) {
          //足夠了
          let tmpbuf2 = tmpbuf.subarray(0, last_len);
          rbuf.set(tmpbuf2, rbuf_ind);
          rbuf_ind += tmpbuf2.length;
          /**向list返还剩下的buf 若last_len = tmplen则刚好，无需返还*/
          if (last_len < tmplen) {
            let newUint8Array = tmpbuf.subarray(last_len, tmplen);
            this.list.unshift(newUint8Array);
          }
          break;
        } else {
          rbuf.set(tmpbuf, rbuf_ind);
          rbuf_ind += tmplen;
        }
      } else {
        rbuf = rbuf.subarray(0, rbuf_ind);
        break;
      }
    }
    this.length -= rbuf.length;
    return rbuf;
  }
  return null;
}

function DevInfo() {
  /**detailInfo是否已经初始化 */
  this.ifInited = false
  this.deviceInfo = []
  this.deviceInfo[0] = {
    usedNum: 0,
    totalNum: 100,
    detailInfo: []
  }
  this.deviceInfo[1] = {
    usedNum: 0,
    totalNum: 20,
    detailInfo: []
  }
  this.deviceInfo[2] = {
    usedNum: 0,
    totalNum: 100,
    detailInfo: []
  }
  for (let index = 0; index < this.deviceInfo.length; index++) {
    for (let i = 0; i < this.deviceInfo[index].totalNum; i++) {
      this.deviceInfo[index].detailInfo[i] = {
        data: 0,
        backup: ''
      }
    }
  }
}

function LockOpInfo() {
  this.info = []
}

function PrefixInteger(num, length) {
  return (Array(length).join('0') + num).slice(-length);
}

function createCode() {
  //首先默认code为空字符串
  var code = '';
  //设置长度
  var codeLength = 6;

  //设置随机字符
//  var random = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z');
  var random = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
//循环codeLength 设置的4就是循环4次
  for (var i = 0; i < codeLength; i++) {
    //设置随机数范围,这设置为0 ~ 9
    var index = Math.floor(Math.random() * 10);
    //字符串拼接 将每次随机的字符 进行拼接
    code += random[index];
  }

  return code;
}

function SendSms(PhoneNumbers) {
  var obj = {
    'code': createCode()
  }
  console.log(obj)
  return new Promise((resolve, reject) => {
    var result
    wx.cloud.callFunction({
      // 云函数名称
      name: 'SendSms',
      // 传给云函数的参数
      data: {
        accessKeyId: 'LTAIvRCkroUViKot',
        accessKeySecret: 'McUOxvnhULoJQMmCebEbLD7xNuZCri',
        PhoneNumbers: PhoneNumbers,
        SignName: "HIKSMARTLOCK",
        TemplateCode: "SMS_162731483",
        TemplateParam: JSON.stringify(obj)
      },
      success(res) {
        console.log(res.result) // 3
        if (res.result.result.Code === 'OK') {
          resolve(obj.code)
        } else {
          result = {
            code: 0,
            res: res.result
          }
          reject(result)
        }
      },
      fail(res) {
        result = {
          code: 1,
          res: res
        }
        reject(result)
      }
    })
  })
}

function checkPhone(phone) {
  return (/^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\d{8}$/.test(phone))
}

/** 网络异常判断 */
function NetStatusOk() {
  return new Promise(function (resolve, reject) {
    wx.getNetworkType({
      success(res) {
        const networkType = res.networkType
        if (networkType === 'none') {
          wx.showToast({
            title: '网络异常，请检查网络',
            icon: 'none',
            duration: 2000
          })
          reject()
        } else {
          resolve()
        }
      },
      fail(){
        reject()
      }
    })
  })
}

function throttle(fn, gapTime) {
  if (gapTime == null || gapTime == undefined) {
    gapTime = 1500
  }

  let _lastTime = null

  // 返回新的函数
  return function () {
    let _nowTime = +new Date()
    if (_nowTime - _lastTime > gapTime || !_lastTime) {
      fn.apply(this, arguments) //将this和参数传给原函数
      _lastTime = _nowTime
    }
  }
}

function AEScrypt(key, iv) {
  this.key = CryptoJS.enc.Utf8.parse(key); //十六位十六进制数作为密钥
  this.iv = CryptoJS.enc.Utf8.parse(iv); //十六位十六进制数作为密钥偏移量
}

//加密方法
AEScrypt.prototype.Encrypt = function (word) {
  let srcs = CryptoJS.enc.Utf8.parse(word);
  let encrypted = CryptoJS.AES.encrypt(srcs, this.key, {
    iv: this.iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  });
  return encrypted.ciphertext.toString().toUpperCase();
}

//解密方法
AEScrypt.prototype.Decrypt = function (word) {
  let encryptedHexStr = CryptoJS.enc.Hex.parse(word);
  let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
  let decrypt = CryptoJS.AES.decrypt(srcs, this.key, {
    iv: this.iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  });
  let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
  return decryptedStr.toString();
}

function stringToByte(str) {
  var bytes = new Array();
  var len;
  len = str.length;
  for (var i = 0; i < len; i+=2) {
    bytes.push(parseInt(str.slice(i, i + 2), 16));
  }
  return bytes;
}

function byteToString(arrBytes) {
  var str = "";
  for (var i = 0; i < arrBytes.length; i++) {
    var tmp;
    var num = arrBytes[i];
    if (num < 0) {
      //此处填坑，当byte因为符合位导致数值为负时候，需要对数据进行处理
      tmp = (255 + num + 1).toString(16);
    } else {
      tmp = num.toString(16);
    }
    if (tmp.length == 1) {
      tmp = "0" + tmp;
    }
    str += tmp;
  }
  return str;
}

module.exports = {
  formatTime: formatTime,
  formatTime1: formatTime1,
  GetCrc16: GetCrc16,
  ByteArray: ByteArray,
  DevInfo: DevInfo,
  LockOpInfo: LockOpInfo,
  PrefixInteger: PrefixInteger,
  SendSms: SendSms,
  checkPhone: checkPhone,
  NetStatusOk: NetStatusOk,
  throttle: throttle,
  AEScrypt: AEScrypt,
  stringToByte: stringToByte,
  byteToString: byteToString,
}
